// PrintReport.cpp : implementation file
//

#include "stdafx.h"
#include "../Frame/GYWalkAidApp.h"
#include "PrintReport.h"
#include "../Common/CommonFun.h"
#include "../Common/GYDataSet.h"
#include "../PatientMan/PatientSelectDlg.h"
#include "../Common/LinkInputNode.h"
#include "../Gait/GaitAnaly.h"
#include "../PatientMan/ZhusuPage.h"
#include "../PatientMan/HisNowPage.h"
#include "../PatientMan/HisPastPage.h"
#include "../Common/ColorCombo.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#define		SCALE_DOCTOR_WRITE				1

#define		SCALE_FOLDER_NAME				_T("Scale")
#define		SCALE_INI_FILE					_T("ScalePrint.ini")
#define		SCALE_SEC_MINI_MENTAL			_T("MINI_MENTAL")
#define		SCALE_SEC_TINETTI_BAL			_T("TINETTI_BAL")
#define		SCALE_SEC_BERG_SCORE			_T("BERG_SCORE")
#define		SCALE_SEC_FUGL_MEYER_UP			_T("FUGL_MEYER_UP")
#define		SCALE_SEC_FUGL_MEYER_LOW		_T("FUGL_MEYER_LOW")
#define		SCALE_SEC_HOLDEN_WALK			_T("HOLDEN_WALK")
#define		SCALE_SEC_FUGL_MEYER_BAL		_T("FUGL_MEYER_BAL")
#define		SCALE_SEC_REVISE_ASHWORTH		_T("REVISE_ASHWORTH")
#define		SCALE_SEC_BRUNN_STORM			_T("BRUNN_STORM")
#define		SCALE_SEC_DOCTOR_CUSTOM			_T("DOCTOR_CUSTOM")

#define		SCALE_KEY_TITLE					_T("Title")
#define		SCALE_KEY_FILE_NAME				_T("FileName")
#define		SCALE_KEY_IMAGE_WIDTH			_T("Width")
#define		SCALE_KEY_IMAGE_HEIGHT			_T("Height")
#define		SCALE_KEY_IMAGE_MARGIN_Y		_T("MarginY")

static struct SCALE_PRINT_INFO
{
	DWORD		dwScaleCheck;
	int			nPageCount;
	TCHAR		szScaleSec[32];
}
s_aScalePrintInfo[] = 
{
	{IDC_CHECK_MINI_MENTAL,		2,	SCALE_SEC_MINI_MENTAL},
	{IDC_CHECK_TINETTI_BAL,		2,	SCALE_SEC_TINETTI_BAL},
	{IDC_CHECK_BERG_SCORE,		2,	SCALE_SEC_BERG_SCORE},
	{IDC_CHECK_FM_UP,			3,	SCALE_SEC_FUGL_MEYER_UP},
	{IDC_CHECK_FM_LOW,			2,	SCALE_SEC_FUGL_MEYER_LOW},
	{IDC_CHECK_HOLDEN_WALK,		1,	SCALE_SEC_HOLDEN_WALK},
	{IDC_CHECK_FM_BAL,			1,	SCALE_SEC_FUGL_MEYER_BAL},
	{IDC_CHECK_REVISE_ASHWORTH,	1,	SCALE_SEC_REVISE_ASHWORTH},
	{IDC_CHECK_BRUNNSTORM,		1,	SCALE_SEC_BRUNN_STORM},
	{IDC_CHECK_DOCTOR_CUSTOM,	1,	SCALE_SEC_DOCTOR_CUSTOM}
};



static INPUT_FIELD_INFO s_InputFieldArray[] = 
{
	{NULL,		IBT_NoneType,	FALSE,	FALSE,	_T("MedicalRecordNo"),		ftString,	FALSE,	IDS_PAT_FIELD_MRN,	10,		CPrintReport::KeyFieldsCheck,		CPrintReport::LostFocusCheck	},
	{NULL,		IBT_NoneType,	FALSE,	FALSE,	_T("Name"),					ftString,	FALSE,	IDS_PAT_FIELD_NAME,	12,		CPrintReport::KeyFieldsCheck,		CPrintReport::LostFocusCheck	},
	{NULL,		IBT_NoneType,	FALSE,	FALSE,	_T("SerialNo"),				ftNumber,	FALSE,	IDS_PAT_FIELD_SN,	10,		CPrintReport::KeyFieldsCheck,		CPrintReport::LostFocusCheck	},
};

#define		PAGE_MARGIN				100
#define		LINE_POS_1				PAGE_MARGIN
#define		LINE_POS_2				(PAGE_MARGIN + 1500)
#define		LINE_POS_3				(PAGE_MARGIN + 3000)

#define		LINE_1_Y				700
#define		LINE_2_Y				(LINE_1_Y + 200)
#define		LINE_3_Y				(LINE_2_Y + 200)
#define		LINE_4_Y				(LINE_3_Y + 200)
#define		LINE_5_Y				(LINE_4_Y + 200)
#define		LINE_6_Y				(LINE_5_Y + 500)

#define		GAIT_GRAPH_Y			(LINE_5_Y + 300)
#define		TEXT_FRAME_Y			(LINE_5_Y + 3500)

#define		MARGIN_FOR_PAGE_TITLE	(LINE_1_Y + PAGE_MARGIN)
#define		MARGIN_FOR_PAGE_FOOT	(PAGE_MARGIN * 2)

#define		MARGIN_TITLE_FRAME		(0.1)
#define		MARGIN_FRAME_TITLE		(0.5)

/////////////////////////////////////////////////////////////////////////////
// CPrintReport dialog


CPrintReport::CPrintReport(CWnd* pParent /*=NULL*/)	: CDialog(CPrintReport::IDD, pParent)
,  m_edtMedicaRecordNo(&s_InputFieldArray[0])
,			 m_edtName(&s_InputFieldArray[1])
,		 m_edtSerialNo(&s_InputFieldArray[2])
{
	//{{AFX_DATA_INIT(CPrintReport)
	m_strDoctorDesc = _T("");
	m_str1stDoctor = _T("");
	m_str1stTime = _T("");
	m_strClinical = _T("");
	m_strStature = _T("");
	//}}AFX_DATA_INIT

	m_pFontForName		= NULL;
	m_pFontTitle		= NULL;
	m_pFontBody			= NULL;
}


void CPrintReport::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CPrintReport)
	DDX_Control(pDX, IDC_EDIT_SERIAL_NO, m_edtSerialNo);
	DDX_Control(pDX, IDC_EDIT_NAME, m_edtName);
	DDX_Control(pDX, IDC_EDIT_MEDICAL_CARD_NO, m_edtMedicaRecordNo);
	DDX_Text(pDX, IDC_EDIT_WEIGHT, m_strWeight);
	DDX_Text(pDX, IDC_EDIT_DATEOFBIRTH, m_strBirth);
	DDX_Text(pDX, IDC_EDIT_GENDER, m_strGender);
	DDX_Text(pDX, IDC_EDIT_HOME_ADDRESS, m_strAddress);
	DDX_Text(pDX, IDC_EDIT_PHONENO, m_strPhoneNo);
	DDX_Text(pDX, IDC_EDIT_DOCTOR_DESC, m_strDoctorDesc);
	DDX_Text(pDX, IDC_EDIT_1ST_CLINIC_DOCTOR, m_str1stDoctor);
	DDX_Text(pDX, IDC_EDIT_1ST_CLINIC_TIME, m_str1stTime);
	DDX_Text(pDX, IDC_EDIT_CLINICAL_DIAG, m_strClinical);
	DDX_Text(pDX, IDC_EDIT_STATURE, m_strStature);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CPrintReport, CDialog)
	//{{AFX_MSG_MAP(CPrintReport)
	ON_BN_CLICKED(IDC_BUTTON_PRINT_CANCEL, OnButtonCancel)
	ON_BN_CLICKED(IDC_BUTTON_PRINT, OnButtonPrint)
	ON_BN_CLICKED(IDC_CHECK_GAIT_GRAPH, OnCheckGaitGraph)
	ON_CBN_SELCHANGE(IDC_COMBO_DATES_GAIT, OnSelchangeComboDatesGait)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CPrintReport message handlers

void CPrintReport::OnButtonCancel() 
{
	CDialog::OnCancel();	
}

BOOL CPrintReport::PreparePrint(CDC* pDC, CPrintInfo* pInfo)
{
	NULL_RETURN_FALSE(pDC);
	NULL_RETURN_FALSE(pInfo);

	UpdateData();

    CPrintDialog printDlg(FALSE);
    if (printDlg.DoModal() == IDCANCEL)         // Get printer settings from user
        return FALSE;
	
    pDC->Attach(printDlg.GetPrinterDC());         // Attach a printer DC
    pDC->m_bPrinting = TRUE;
	
    CString strTitle;                           // Get the application title
    strTitle.LoadString(AFX_IDS_APP_TITLE);
	
	
    // Get the printing extents and store in the m_rectDraw field of a CPrintInfo object
    pInfo->m_rectDraw.SetRect(0, 0, pDC->GetDeviceCaps(HORZRES), pDC->GetDeviceCaps(VERTRES));

    DOCINFO di;                                 // Initialize print document details
    ::ZeroMemory (&di, sizeof (DOCINFO));
    di.cbSize = sizeof (DOCINFO);
    di.lpszDocName = strTitle;
	
	ASSERT(m_pFontTitle == NULL);
	m_pFontTitle = new CFont();
	NULL_RETURN_FALSE(m_pFontTitle);

	LOGFONT   lfTitle	= {0};   
	lfTitle.lfHeight	= 256;
	lfTitle.lfWidth		= 128;
	if(!m_pFontTitle->CreateFontIndirect(&lfTitle))
		return FALSE;

	ASSERT(m_pFontBody == NULL);
	m_pFontBody = new CFont();
	NULL_RETURN_FALSE(m_pFontBody);
	
	LOGFONT   lfBody	= {0};   
	lfBody.lfHeight		= 96;
	lfBody.lfWidth		= 48;
	if(!m_pFontBody->CreateFontIndirect(&lfBody))
		return FALSE;

	ASSERT(m_pFontForName == NULL);
	m_pFontForName = new CFont();
	NULL_RETURN_FALSE(m_pFontForName);
	
	LOGFONT   lfName	= {0};   
	lfName.lfHeight		= 128;
	lfName.lfWidth		= 64;
	lfName.lfWeight		= FW_BOLD;
	if(!m_pFontForName->CreateFontIndirect(&lfName))
		return FALSE;

	int nStartPrint = pDC->StartDoc(&di);        // Begin a new print job
	return (nStartPrint > 0);
}

BOOL CPrintReport::ClearUpPrint(CDC* pDC, BOOL bPrintingOK)
{
	if(pDC && pDC->m_hDC)
	{
		bPrintingOK ? pDC->EndDoc() : pDC->AbortDoc();
		pDC->Detach();
	}
	
	SAFE_DELETE(m_pFontTitle);
	SAFE_DELETE(m_pFontBody);
	SAFE_DELETE(m_pFontForName);

	return TRUE;
}

void CPrintReport::OnButtonPrint() 
{
	if(m_strMRN.IsEmpty())
	{
		GYMsgBox(IDS_PRT_PAT_INFO_EMPTY, MB_ICONSTOP|MB_OK);
		return;
	}

	m_edtSerialNo.SetWindowText(m_strMRNCode);
	m_edtName.SetWindowText(m_strPatName);
	m_edtMedicaRecordNo.SetWindowText(m_strMRN);

	CDC dc;
	CPrintInfo Info;

	BOOL bPrintingOK = TRUE;
	while(1)
	{
		bPrintingOK = PreparePrint(&dc, &Info);
		if(!bPrintingOK)
			break;

		CWaitCursor waitcursor;
		int nPageTotal = SumPrintPageCount();

		//  1st page
		UINT page = Info.GetMinPage();
		bPrintingOK = PrintFirstPage(&dc, &Info, nPageTotal, page);
		if(!bPrintingOK)
			break;
		
		//  Zhusu
		CButton* pCheckZhusu = (CButton*)GetDlgItem(IDC_CHECK_PRINT_ZHUSU);
		ASSERT(pCheckZhusu);
		BOOL bPrintZhusu = pCheckZhusu->GetCheck();
		//  Disease history now
		CButton* pCheckHistNow = (CButton*)GetDlgItem(IDC_CHECK_PRINT_DISHISNOW);
		ASSERT(pCheckHistNow);
		BOOL bPrintHistNow = pCheckHistNow->GetCheck();
		//  Disease history past
		CButton* pCheckHistPast = (CButton*)GetDlgItem(IDC_CHECK_PRINT_DISHISPAST);
		ASSERT(pCheckHistPast);
		BOOL bPrintHistPast = pCheckHistPast->GetCheck();
		if(bPrintZhusu || bPrintHistNow || bPrintHistPast)
		{
			bPrintingOK = PrintZNP(&dc, &Info, nPageTotal, page, bPrintZhusu, bPrintHistNow, bPrintHistPast);
			if(!bPrintingOK)
				break;
		}
		
		//  print Body check scales, exclude Doctor Write Scale
		for(int j = 0; bPrintingOK && j < ARRAY_ELE_COUNT(s_aScalePrintInfo) - 1; j++)
		{
			CButton* pScaleCheck = (CButton*)GetDlgItem(s_aScalePrintInfo[j].dwScaleCheck);
			ASSERT(pScaleCheck);
			
			if(pScaleCheck->GetCheck())
				bPrintingOK = PrintScale(&dc, &Info, page, nPageTotal, s_aScalePrintInfo[j].szScaleSec);
		}

		if(!bPrintingOK)
			break;
		
		//  Doctor Write Scale
		CButton* pScaleDoctorWrite = (CButton*)GetDlgItem(s_aScalePrintInfo[7].dwScaleCheck);
		ASSERT(pScaleDoctorWrite);
		if(pScaleDoctorWrite->GetCheck())
			bPrintingOK = PrintDoctorWriteScale(&dc, &Info, nPageTotal, page);

		break;
	}

	ClearUpPrint(&dc, bPrintingOK);
}

BOOL CPrintReport::KeyFieldsCheck(LPVOID pParam)
{
	if(pParam)
	{
		INPUT_FIELD_INFO* pFieldInfo = (INPUT_FIELD_INFO*)pParam;
		CLinkEdit* pEdit = (CLinkEdit*)pFieldInfo->pLinkCtrl;
		if(pEdit)
		{
			CString strNowText = pEdit->GetControlData(TRUE, FALSE);
			CPrintReport* pThis = (CPrintReport*)pEdit->GetParent();
			if(pThis)
			{
				INPUT_FIELD_INFO* pFieldInfo = pEdit->GetFieldInfo();
				if(pFieldInfo && pFieldInfo->szFieldName)
				{
					if(strNowText.IsEmpty())
						return TRUE;
					else
						pThis->ShowTablePatientInfo(pEdit, pFieldInfo->szFieldName, strNowText);
				}
			}
		}
	}
	
	return FALSE;
}

BOOL CPrintReport::LostFocusCheck(LPVOID pParam)
{
	return TRUE;
}

BOOL CPrintReport::ShowTablePatientInfo(CLinkEdit* pLinkEdit, CString strFieldName, CString strFieldValue)
{
	CString strSQL;
	strFieldValue.Replace(_T("'"), _T("''"));
	strSQL.Format(_T("SELECT * FROM PatientInfo WHERE %s='%s'"), strFieldName, strFieldValue);
	
	CGYDataSet tblPatInfo;
	tblPatInfo.OpenTable(strSQL);
	
	int nRecCnt = 0;
	for(; !tblPatInfo.IsEOF(); tblPatInfo.MoveNext(), nRecCnt++);
	
	if(nRecCnt <= 0)
	{
		UpdateData();

		m_edtMedicaRecordNo.SetWindowText(_T(""));
		m_edtName.SetWindowText(_T(""));
		m_edtSerialNo.SetWindowText(_T(""));
		
		m_strGender.Empty();
		m_strStature.Empty();
		m_strWeight.Empty();
		m_strBirth.Empty();
		m_strPhoneNo.Empty();
		m_str1stDoctor.Empty();
		m_str1stTime.Empty();
		m_strAddress.Empty();
		m_strClinical.Empty();

		m_strMRN.Empty();
		m_strMRNCode.Empty();
		m_strPatName.Empty();

		UpdateData(FALSE);
	}
	else if(nRecCnt == 1)
	{
		return ShowPatientInfoFromTable(&tblPatInfo, 0);
	}
	else
	{
		CPatientSelectDlg dlg(&tblPatInfo);
		if(dlg.DoModal() == IDOK)
		{
			int nIndex = dlg.GetSelectIndex();
			return ShowPatientInfoFromTable(&tblPatInfo, nIndex);
		}
	}
	
	return TRUE;
}

BOOL CPrintReport::ShowPatientInfoFromTable(CGYDataSet* pDataSet, int nIndex)
{
	if(pDataSet->GetRecordCount() <= 0)
	{
		m_strMRN = _T("");
		return FALSE;
	}
	
	UpdateData();

	int nMove = 0;
	for(pDataSet->MoveFirst(); !pDataSet->IsEOF() && nMove < nIndex; pDataSet->MoveNext(), nMove++);

	CString strValue;
	pDataSet->GetFieldValue(_T("MedicalRecordNo"), strValue);
	m_edtMedicaRecordNo.SetWindowText(strValue);

	m_strMRN = strValue;

	pDataSet->GetFieldValue(_T("Name"), strValue);
	m_edtName.SetWindowText(strValue);
	m_strPatName = strValue;
	
	pDataSet->GetFieldValue(_T("SerialNo"), strValue);
	m_edtSerialNo.SetWindowText(strValue);

	m_strMRNCode = m_edtSerialNo.GetControlData();
	
	pDataSet->GetFieldValue(_T("Gender"), strValue);
	m_strGender = (strValue == _T("0") ? GetResString(IDS_PAT_MALE) : GetResString(IDS_PAT_FEMALE));
	
	pDataSet->GetFieldValue(_T("Stature"), m_strStature);
	pDataSet->GetFieldValue(_T("Weight"), m_strWeight);
	pDataSet->GetFieldValue(_T("DateOfBirth"), m_strBirth);
	m_strBirth = m_strBirth.Left(10);
	pDataSet->GetFieldValue(_T("PhoneNo"), m_strPhoneNo);
	pDataSet->GetFieldValue(_T("FirstClinicDoctor"), m_str1stDoctor);
	pDataSet->GetFieldValue(_T("FirstClinicTime"), m_str1stTime);
	m_str1stTime = m_str1stTime.Left(10);
	pDataSet->GetFieldValue(_T("HomeAddress"), m_strAddress);
	pDataSet->GetFieldValue(_T("ClinicalDiagnosis"), m_strClinical);

	//  get gait from table
	CComboBox* pComboGaitDate = (CComboBox*)GetDlgItem(IDC_COMBO_DATES_GAIT);
	ASSERT(pComboGaitDate);
	pComboGaitDate->ResetContent();

	CString strSQL;
	strSQL.Format(_T("SELECT DiagDate, DiagSN FROM DiagRecord WHERE MedicalRecordNo='%s' AND DiagSN>=0 ORDER BY DiagSN"), m_strMRN);

	int nItemIndex = 0;
	CGYDataSet setGait;
	for(setGait.OpenTable(strSQL); !setGait.IsEOF(); setGait.MoveNext())
	{
		CString strDiagDate;
		setGait.GetFieldValue(_T("DiagDate"), strDiagDate);

		strDiagDate = strDiagDate.Left(10);

		CString strDiagSN;
		setGait.GetFieldValue(_T("DiagSN"), strDiagSN);

		CString strGaitInfo;
		int nDiagSN = _ttoi(strDiagSN);

		if(nDiagSN == 0)
			strGaitInfo.Format(_T("%s  %s"), strDiagDate, GetResString(IDS_QRY_1ST_DIAG));
		else
			strGaitInfo.Format(_T("%s  %s %d"), strDiagDate, GetResString(IDS_TABTITLE_SUBSEDIAG), nDiagSN);

		pComboGaitDate->AddString(strGaitInfo);
		pComboGaitDate->SetItemData(nItemIndex++, nDiagSN);
	}

	CButton* pCheckGait = (CButton*)GetDlgItem(IDC_CHECK_GAIT_GRAPH);
	ASSERT(pCheckGait);
	if(pComboGaitDate->GetCount() > 0)
	{
		pCheckGait->EnableWindow(TRUE);
		pCheckGait->SetCheck(FALSE);

		pComboGaitDate->SetCurSel(0);
		OnSelchangeComboDatesGait();
	}
	else
	{
		pCheckGait->EnableWindow(FALSE);
		pComboGaitDate->EnableWindow(FALSE);
	}

	for(int i = 0; i < ARRAY_ELE_COUNT(s_aScalePrintInfo); i++)
	{
		CWnd* pScale = GetDlgItem(s_aScalePrintInfo[i].dwScaleCheck);
		ASSERT(pScale);
		pScale->EnableWindow(TRUE);
	}

	GetDlgItem(IDC_BUTTON_PRINT)->EnableWindow(TRUE);
	UpdateData(FALSE);

	return TRUE;
}

void CPrintReport::OnOK()
{
	
}

void CPrintReport::OnCancel()
{

}

BOOL CPrintReport::OnInitDialog() 
{
	CDialog::OnInitDialog();

	CLinkInputNode::EnableCheckValid(TRUE, IBT_AllType, this);

	for(int i = 0; i < ARRAY_ELE_COUNT(s_aScalePrintInfo); i++)
	{
		CWnd* pScale = GetDlgItem(s_aScalePrintInfo[i].dwScaleCheck);
		ASSERT(pScale);
		pScale->EnableWindow(FALSE);
	}

	CButton* pCheckGait = (CButton*)GetDlgItem(IDC_CHECK_GAIT_GRAPH);
	ASSERT(pCheckGait);
	pCheckGait->EnableWindow(FALSE);

	GetDlgItem(IDC_BUTTON_PRINT)->EnableWindow(FALSE);
	
	return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
}

BOOL CPrintReport::PrintScale(CDC* pDC, CPrintInfo* pInfo, UINT& nPageNum, UINT unPageTotal, TCHAR* szScaleName)
{
	//  draw image
	CString strFileName = SCALE_FOLDER_NAME;
	strFileName += _T("\\") + GetIniStringValue(szScaleName, SCALE_KEY_FILE_NAME);
	
	HBITMAP hbitmap = (HBITMAP)LoadImage(NULL, strFileName, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
	CBitmap bmp;
	bmp.Attach(hbitmap);

	CDC memDC;
	memDC.CreateCompatibleDC(NULL);
	memDC.SelectObject(&bmp);

	//  Read body check value
	POINT aDates[3] = {0};
	aDates[0].x = GetIniIntValue(szScaleName, _T("DATE1POSX"));
	aDates[0].y = GetIniIntValue(szScaleName, _T("DATE1POSY"));
	aDates[1].x = GetIniIntValue(szScaleName, _T("DATE2POSX"));
	aDates[1].y = GetIniIntValue(szScaleName, _T("DATE2POSY"));
	aDates[2].x = GetIniIntValue(szScaleName, _T("DATE3POSX"));
	aDates[2].y = GetIniIntValue(szScaleName, _T("DATE3POSY"));

	int nCol1X = GetIniIntValue(szScaleName, _T("COL1X"));
	int nCol2X = GetIniIntValue(szScaleName, _T("COL2X"));
	int nCol3X = GetIniIntValue(szScaleName, _T("COL3X"));

	int nValueCount = GetIniIntValue(szScaleName, _T("ROWCOUNT"));
	POINT* pCol1 = new POINT[nValueCount];
	POINT* pCol2 = new POINT[nValueCount];
	POINT* pCol3 = new POINT[nValueCount];
	for(int i = 0; i < nValueCount; i++)
	{
		CString strKey;
		strKey.Format(_T("ROW%dY"), i + 1);

		pCol1[i].x = nCol1X;
		pCol2[i].x = nCol2X;
		pCol3[i].x = nCol3X;

		pCol1[i].y = pCol2[i].y = pCol3[i].y = GetIniIntValue(szScaleName, strKey);
	}

	POINT* ppValues[3];
	ppValues[0] = pCol1;
	ppValues[1] = pCol2;
	ppValues[2] = pCol3;

	CString strMRN = m_edtMedicaRecordNo.GetControlData();
	DWORD dwScaleId = GetIniIntValue(szScaleName, _T("ScaleId"));

	//  prepare the scale image memory DC
	CComboBox* pDateDiagSN = (CComboBox*)GetDlgItem(IDC_COMBO_DATES_GAIT);
	ASSERT(pDateDiagSN);

	CString strDaigDate;
	int nSel = pDateDiagSN->GetCurSel();
	pDateDiagSN->GetLBText(nSel, strDaigDate);

	strDaigDate = strDaigDate.Left(10);
	int nDiagSN = pDateDiagSN->GetItemData(nSel);

	PrintTableData(&memDC, strMRN, nDiagSN, strDaigDate, dwScaleId, ppValues, nValueCount, aDates);

	int nImagePixelWidth = GetIniIntValue(szScaleName, SCALE_KEY_IMAGE_WIDTH);
	int nImagePixelHeight = GetIniIntValue(szScaleName, SCALE_KEY_IMAGE_HEIGHT);
	int nImageMarginY = GetIniIntValue(szScaleName, SCALE_KEY_IMAGE_MARGIN_Y);

	double dRatio = (pInfo->m_rectDraw.Width() - PAGE_MARGIN * 2.0) / nImagePixelWidth;
	double dPageHeight = pInfo->m_rectDraw.Height() - MARGIN_FOR_PAGE_TITLE - nImageMarginY - MARGIN_FOR_PAGE_FOOT;
	double dPagePixelsHeight = dPageHeight / dRatio;

	//  a scale image may be printed in several pages
	for(double dHeightLeftToPring = nImagePixelHeight; dHeightLeftToPring > 0; dHeightLeftToPring -= dPagePixelsHeight)
	{
		pDC->StartPage();
		
		// Title
		CString strTitle = GetIniStringValue(szScaleName, SCALE_KEY_TITLE);
		PrintPageTitle(pDC, pInfo, unPageTotal, nPageNum, strTitle, TRUE);

		//  scale image
		double dImageHeightPrintInOnePage = min(dHeightLeftToPring, dPagePixelsHeight);
		pDC->StretchBlt(PAGE_MARGIN, MARGIN_FOR_PAGE_TITLE + nImageMarginY, nImagePixelWidth * dRatio, dImageHeightPrintInOnePage * dRatio, &memDC, 0, nImagePixelHeight - dHeightLeftToPring, nImagePixelWidth, dImageHeightPrintInOnePage, SRCCOPY);

		//  Foot
		PrintPageFoot(pDC, pInfo->m_rectDraw, unPageTotal, nPageNum);

		pDC->EndPage();
		nPageNum++;
	}

	bmp.Detach();
	::DeleteObject(hbitmap);

	SAFE_DELETE(pCol1);
	SAFE_DELETE(pCol2);
	SAFE_DELETE(pCol3);

	return TRUE;
}

CString CPrintReport::GetIniStringValue(CString strSection, CString strKey)
{
	CString strIniFile = GetExePath();
	strIniFile += _T("\\");
	strIniFile += SCALE_INI_FILE;

	TCHAR szValue[MAX_PATH] = {0};
	::GetPrivateProfileString(strSection, strKey, _T(""), szValue, MAX_PATH, strIniFile);

	return szValue;
}

int CPrintReport::GetIniIntValue(CString strSection, CString strKey)
{
	CString strIniFile = GetExePath();
	strIniFile += _T("\\");
	strIniFile += SCALE_INI_FILE;
	
	return ::GetPrivateProfileInt(strSection, strKey, 0, strIniFile);
}

BOOL CPrintReport::PrintTableData(CDC* pDC, CString strMRN, int nDiagSN, CString strDaigDate, DWORD dwScaleID, POINT* ppCtrlArrays[], int nColCtrlCount, POINT pDateLabelArray[])
{
	CString strSQL;
	strSQL.Format(_T("SELECT CheckDate, DiagSN, BCID FROM BodyCheckReg WHERE MedicalRecordNo='%s' AND DiagSN<=%d AND ScaleID=%d ORDER BY DiagSN DESC LIMIT 3"), strMRN, nDiagSN, dwScaleID);
	
	CGYDataSet tblBCReg;
	tblBCReg.OpenTable(strSQL);
	if(tblBCReg.IsEOF())
		return TRUE;
	
	CFont   fontBody;   
	LOGFONT   lfBody = {0};   
	lfBody.lfHeight   =   4;
	lfBody.lfWidth    =   4;
	fontBody.CreateFontIndirect(&lfBody);
	pDC->SelectObject(&lfBody);

	CString astrCheckDate[3];
	CString astrDiagSN[3];
	CString astrBCID[3];

	BOOL bSpecifyDiagSNExist = TRUE;

	for(int i = 2;!tblBCReg.IsEOF() && i >= 0; tblBCReg.MoveNext(), i--)
	{
		CString strChkDate;
		CString strBCid;
		CString strDiagSN;
		
		tblBCReg.GetFieldValue(_T("CheckDate"), strChkDate);
		tblBCReg.GetFieldValue(_T("BCID"), strBCid);
		tblBCReg.GetFieldValue(_T("DiagSN"), strDiagSN);

		strChkDate = strChkDate.Left(10);

		//  the specified Diagnose SN is exist? If not, start at next col
		if(i == 2)
		{
			if(_ttoi(strDiagSN) != nDiagSN)
			{
				astrCheckDate[i] = strDaigDate;
				astrDiagSN[i].Format(_T("%d"), nDiagSN);
				astrBCID[i] = _T("0");

				i--;
				if(i < 0)
					break;
				
				bSpecifyDiagSNExist = FALSE;
			}
		}
		astrCheckDate[i] = strChkDate;
		astrDiagSN[i] = strDiagSN;
		astrBCID[i] = strBCid;
	}
	tblBCReg.Close();

	//  print Check Date, Diagnose SN on col title
	for(i = 2; i >= 0; i--)
	{
		if(!astrCheckDate[i].IsEmpty())
		{
			pDC->TextOut(pDateLabelArray[i].x, pDateLabelArray[i].y, astrCheckDate[i]);
			
			CString strDiag;
			if(astrDiagSN[i] == _T("0"))
				strDiag = GetResString(IDS_QRY_1ST_DIAG);
			else
				strDiag.Format(_T("%s %s"), GetResString(IDS_TABTITLE_SUBSEDIAG), astrDiagSN[i]);
			
			pDC->TextOut(pDateLabelArray[i].x + 10, pDateLabelArray[i].y + 22, strDiag);
		}
	}

	//  print every body check item value
	for(int j = (bSpecifyDiagSNExist ? 2 : 1); j >= 0 && !astrBCID[j].IsEmpty(); j--)
	{
		strSQL.Format(_T("SELECT FieldID, FieldValue FROM BodyCheckResult WHERE BCID=%s ORDER BY FieldID"), astrBCID[j]);
		
		CGYDataSet tblBCResult;
		tblBCResult.OpenTable(strSQL);
		
		CString strFieldID, strFieldValue;
		
		for(int i = 0; !tblBCResult.IsEOF(); tblBCResult.MoveNext(), i++)
		{
#ifdef _DEBUG
			tblBCResult.GetFieldValue(_T("FieldID"), strFieldID);
#endif
			tblBCResult.GetFieldValue(_T("FieldValue"), strFieldValue);
			
			pDC->TextOut(ppCtrlArrays[j][i].x, ppCtrlArrays[j][i].y, strFieldValue);
		}
	}
	
	return TRUE;
}

void CPrintReport::PrintPageTitle(CDC* pDC, CPrintInfo* pInfo, UINT unPageTotal, UINT nPageNum, CString strTitle, BOOL bDrawDiagSN)
{
	RECT rectTitle		= {0};
	rectTitle.left		= PAGE_MARGIN;
	rectTitle.top		= PAGE_MARGIN;
	rectTitle.right		= pInfo->m_rectDraw.Width() - PAGE_MARGIN;
	rectTitle.bottom	= MARGIN_FOR_PAGE_TITLE;
	
	//  Draw title
	pDC->SelectObject(m_pFontTitle);
	pDC->DrawText(strTitle, &rectTitle, DT_SINGLELINE|DT_CENTER);

	if(bDrawDiagSN)
	{
		CString strMRNCode;
		m_edtSerialNo.GetWindowText(strMRNCode);
		
		CString strDateSN;
		CComboBox* pComboSnapDate = (CComboBox*)GetDlgItem(IDC_COMBO_DATES_GAIT);
		ASSERT(pComboSnapDate);
		int nSel = pComboSnapDate->GetCurSel();
		pComboSnapDate->GetLBText(nSel, strDateSN);
		
		//  Draw date and diagnose serial no
		pDC->SelectObject(m_pFontBody);
		pDC->DrawText(strDateSN, &rectTitle, DT_SINGLELINE|DT_RIGHT|DT_BOTTOM);
	}
}

void CPrintReport::PrintPageFoot(CDC* pDC, CRect rectPage, UINT unPageTotal, UINT nPageNum)
{
	CString strPageNum;
	strPageNum.Format(_T("Page %d of %d"), nPageNum, unPageTotal);

	RECT rectFoot		= {0};
	rectFoot.left		= PAGE_MARGIN;
	rectFoot.right		= rectPage.Width() - PAGE_MARGIN;
	rectFoot.top		= rectPage.Height() - MARGIN_FOR_PAGE_FOOT;
	rectFoot.bottom		= rectPage.Height();

	pDC->SelectObject(m_pFontBody);
	pDC->DrawText(strPageNum, &rectFoot, DT_SINGLELINE|DT_RIGHT);
}

CString CPrintReport::GetDoctorWriteString()
{
	CString strMRN;
	m_edtMedicaRecordNo.GetWindowText(strMRN);

	CString strSQL;
	strSQL.Format(_T("SELECT CheckDate, BCID FROM BodyCheckReg WHERE MedicalRecordNo='%s' AND ScaleID=%d ORDER BY CheckDate DESC LIMIT 1"), strMRN, SCALE_DOCTOR_WRITE);
	
	CString strCheckDate;
	CString strBCID;
	
	CGYDataSet tblDoctWrite;
	tblDoctWrite.OpenTable(strSQL);
	if(tblDoctWrite.IsEOF())
		return _T("");
	
	tblDoctWrite.GetFieldValue(_T("CheckDate"), strCheckDate);
	tblDoctWrite.GetFieldValue(_T("BCID"), strBCID);
	tblDoctWrite.Close();
	
	if(strBCID.IsEmpty())
		return _T("");
	
	strSQL.Format(_T("SELECT FieldID, FieldValue FROM BodyCheckDoctWrite WHERE BCID=%s ORDER BY FieldID"), strBCID);
	
	CGYDataSet tblBCResult;
	tblBCResult.OpenTable(strSQL);
	if(tblBCResult.IsEOF())
		return _T("");
	
	CString strFieldValue;
	tblBCResult.GetFieldValue(_T("FieldValue"), strFieldValue);
	return strFieldValue;
}

BOOL CPrintReport::PrintDoctorWriteScale(CDC* pDC, CPrintInfo* pInfo, UINT unPageTotal, UINT& nPageNum)
{
	CString strTitle = GetResString(IDS_BCTAB_DOCTOR_WRITE);
	CString strDoctorText = GetDoctorWriteString();

	return PrintOneString(pDC, pInfo, unPageTotal, nPageNum, strTitle, strDoctorText, TRUE);
}

void CPrintReport::OnCheckGaitGraph() 
{
	CComboBox* pComboGaitDate = (CComboBox*)GetDlgItem(IDC_COMBO_DATES_GAIT);
	ASSERT(pComboGaitDate);

	CButton* pCheckGait = (CButton*)GetDlgItem(IDC_CHECK_GAIT_GRAPH);
	ASSERT(pCheckGait);
}

int CPrintReport::SumPrintPageCount()
{
	//  count how many pages
	int nPageTotal = 1;
	
	CButton* pCheckZhusu = (CButton*)GetDlgItem(IDC_CHECK_PRINT_ZHUSU);
	ASSERT(pCheckZhusu);
	CButton* pCheckNowHist = (CButton*)GetDlgItem(IDC_CHECK_PRINT_DISHISNOW);
	ASSERT(pCheckNowHist);
	CButton* pCheckPastHist = (CButton*)GetDlgItem(IDC_CHECK_PRINT_DISHISPAST);
	ASSERT(pCheckPastHist);

	if(pCheckZhusu->GetCheck() || pCheckNowHist->GetCheck() || pCheckPastHist->GetCheck())
		nPageTotal++;
	
// 	CButton* pCheckGait = (CButton*)GetDlgItem(IDC_CHECK_GAIT_GRAPH);
// 	ASSERT(pCheckGait);
// 	if(pCheckGait->GetCheck())
// 		nPageTotal++;
	
	for(int i = 0; i < ARRAY_ELE_COUNT(s_aScalePrintInfo); i++)
	{
		CButton* pScaleCheck = (CButton*)GetDlgItem(s_aScalePrintInfo[i].dwScaleCheck);
		ASSERT(pScaleCheck);
		
		if(pScaleCheck->GetCheck())
		{
			nPageTotal += s_aScalePrintInfo[i].nPageCount;
		}
	}

	return nPageTotal;
}

BOOL CPrintReport::PrintFirstPage(CDC* pDC, CPrintInfo* pInfo, int nTotalPage, UINT& page)
{
	NULL_RETURN_FALSE(pDC);

	pDC->StartPage();                         // begin new page
	pInfo->m_nCurPage = page;
	
	CRect rectText;
	rectText.left = PAGE_MARGIN;
	rectText.top = PAGE_MARGIN;
	rectText.right = pInfo->m_rectDraw.Width() - PAGE_MARGIN;
	rectText.bottom = pInfo->m_rectDraw.Height();
	pDC->SelectObject(m_pFontForName);
	
	//  Hospital Name
	CString strHospitalName = GetHospitalName();
	pDC->DrawText(strHospitalName, &rectText, DT_SINGLELINE|DT_CENTER);
	CSize sizeHospitalNameSize = pDC->GetTextExtent(strHospitalName);

	//  Report Name
	rectText.top = PAGE_MARGIN + sizeHospitalNameSize.cy * 2;
	pDC->DrawText(GetResString(IDS_PRT_DIAG_REPORT), &rectText, DT_SINGLELINE|DT_CENTER);

	//  Print date
	CString strReportDate = GetResString(IDS_PRT_REPORT_DATE);
	CTime tCur = CTime::GetCurrentTime();
	strReportDate += tCur.Format(_T("%Y-%m-%d"));

	pDC->SelectObject(m_pFontBody);
	rectText.top = PAGE_MARGIN + sizeHospitalNameSize.cy * 3;

	pDC->DrawText(strReportDate, &rectText, DT_SINGLELINE|DT_RIGHT);
	CSize sizeDateSize = pDC->GetTextExtent(strReportDate);

	CPen penLineBlack;
	penLineBlack.CreatePen(PS_SOLID, max(5, sizeDateSize.cy / 10), RGB(0,0,0));
	pDC->SelectObject(&penLineBlack);
	
	rectText.top = PAGE_MARGIN + sizeHospitalNameSize.cy * 3 + sizeDateSize.cy * 1.2;
	pDC->MoveTo(rectText.left, rectText.top);
	pDC->LineTo(rectText.right, rectText.top);

	//  Basic info of patient
	CString strText;
	GetDlgItem(IDC_STATIC_MRN)->GetWindowText(strText);
	pDC->TextOut(LINE_POS_1, LINE_1_Y, strText + _T(":"));
	m_edtMedicaRecordNo.GetWindowText(strText);
	pDC->TextOut(LINE_POS_1 + 500, LINE_1_Y, strText);
	
	GetDlgItem(IDC_STATIC_NAME)->GetWindowText(strText);
	pDC->TextOut(LINE_POS_2, LINE_1_Y, strText + _T(":"));
	m_edtName.GetWindowText(strText);
	pDC->TextOut(LINE_POS_2 + 500, LINE_1_Y, strText);
	
	GetDlgItem(IDC_STATIC_SN)->GetWindowText(strText);
	pDC->TextOut(LINE_POS_3, LINE_1_Y, strText + _T(":"));
	m_edtSerialNo.GetWindowText(strText);
	pDC->TextOut(LINE_POS_3 + 500, LINE_1_Y, strText);
	
	GetDlgItem(IDC_STATIC_GENDER)->GetWindowText(strText);
	pDC->TextOut(LINE_POS_1, LINE_2_Y, strText + _T(":"));
	pDC->TextOut(LINE_POS_1 + 500, LINE_2_Y, m_strGender);
	
	GetDlgItem(IDC_STATIC_STATURE)->GetWindowText(strText);
	pDC->TextOut(LINE_POS_2, LINE_2_Y, strText + _T(":"));
	pDC->TextOut(LINE_POS_2 + 500, LINE_2_Y, m_strStature);
	
	GetDlgItem(IDC_STATIC_WEIGHT)->GetWindowText(strText);
	pDC->TextOut(LINE_POS_3, LINE_2_Y, strText + _T(":"));
	pDC->TextOut(LINE_POS_3 + 500, LINE_2_Y, m_strWeight);
	
	GetDlgItem(IDC_STATIC_DATEOFBIRTH)->GetWindowText(strText);
	pDC->TextOut(LINE_POS_1, LINE_3_Y, strText + _T(":"));
	pDC->TextOut(LINE_POS_1 + 500, LINE_3_Y, m_strBirth);
	
	GetDlgItem(IDC_STATIC_PHONENO)->GetWindowText(strText);
	pDC->TextOut(LINE_POS_2, LINE_3_Y, strText + _T(":"));
	pDC->TextOut(LINE_POS_2 + 500, LINE_3_Y, m_strPhoneNo);
	
	GetDlgItem(IDC_STATIC_1STDOCTOR)->GetWindowText(strText);
	pDC->TextOut(LINE_POS_3, LINE_3_Y, strText + _T(":"));
	pDC->TextOut(LINE_POS_3 + 500, LINE_3_Y, m_str1stDoctor);
	
	GetDlgItem(IDC_STATIC_1STTIME)->GetWindowText(strText);
	pDC->TextOut(LINE_POS_1, LINE_4_Y, strText + _T(":"));
	pDC->TextOut(LINE_POS_1 + 500, LINE_4_Y, m_str1stTime);
	
	GetDlgItem(IDC_STATIC_ADDRESS)->GetWindowText(strText);
	pDC->TextOut(LINE_POS_2, LINE_4_Y, strText + _T(":"));
	pDC->TextOut(LINE_POS_2 + 500, LINE_4_Y, m_strAddress);
	
	GetDlgItem(IDC_STATIC_DIAG)->GetWindowText(strText);
	pDC->TextOut(LINE_POS_1, LINE_5_Y, strText + _T(":"));
	pDC->TextOut(LINE_POS_1 + 500, LINE_5_Y, m_strClinical);
	
	//  The position when no gait
	rectText.left = PAGE_MARGIN;
	rectText.top = LINE_6_Y;

	//  Gait
	CButton* pCheckGait = (CButton*)GetDlgItem(IDC_CHECK_GAIT_GRAPH);
	ASSERT(pCheckGait);
	if(pCheckGait->GetCheck())
	{
		if(!PrintGaitInFirstPage(pDC, pInfo))
			return FALSE;

		rectText.top = TEXT_FRAME_Y;
	}

	CString strPhaseSummary = GetResString(IDS_PRT_PHASE_SUMMARY);
	CSize sizeTextSize = pDC->GetTextExtent(strPhaseSummary);
	pDC->TextOut(PAGE_MARGIN, rectText.top - sizeTextSize.cy * 1.2, strPhaseSummary);

	rectText.right = pInfo->m_rectDraw.Width() - PAGE_MARGIN;
	rectText.bottom = pInfo->m_rectDraw.Height() - PAGE_MARGIN * 3;
	pDC->Rectangle(rectText);
	
	rectText.DeflateRect(PAGE_MARGIN, PAGE_MARGIN);
	pDC->DrawText(m_strDoctorDesc, &rectText, DT_WORDBREAK);
	
	CString strDoctorName = GetResString(IDS_PRT_DOCTOR);
	strDoctorName += GetApp()->GetUserRealName();
	
	int nSignLine = pInfo->m_rectDraw.Height() - PAGE_MARGIN * 5;
	pDC->TextOut(pInfo->m_rectDraw.Width() - 2500, nSignLine, strDoctorName);
	pDC->TextOut(pInfo->m_rectDraw.Width() - 1300, nSignLine, GetResString(IDS_PRT_DIAG_DOC_SIGN));
	
	PrintPageFoot(pDC, pInfo->m_rectDraw, nTotalPage, page);
	
	BOOL bPrintingOK = (pDC->EndPage() > 0);
	page++;

	return bPrintingOK;
}

BOOL CPrintReport::PrintGaitGraph(CDC* pDC, CPrintInfo* pInfo, int nTotalPage, UINT& page)
{
	NULL_RETURN_FALSE(pDC);
	NULL_RETURN_FALSE(pInfo);

	pDC->StartPage();                         // begin new page
	
	//  page title 
	PrintPageTitle(pDC, pInfo, nTotalPage, page, GetResString(IDS_GAIT_GRAPH), TRUE);
	
	CString strDateSN;
	CComboBox* pComboSnapDate = (CComboBox*)GetDlgItem(IDC_COMBO_DATES_GAIT);
	ASSERT(pComboSnapDate);
	int nSel = pComboSnapDate->GetCurSel();
	pComboSnapDate->GetLBText(nSel, strDateSN);

	CString strDate = strDateSN.Left(10);
	int nDiagSN = pComboSnapDate->GetItemData(nSel);
	
	int nStartPos = 0;
	int nTriggerOpen = 0;
	int nTriggerClose = 0;
	
	DWORD dwGaitPoints[GAIT_POINT_ARRAY_SIZE] = {0};
	CString strDevID;
	CString strDevAddress;
	BOOL bRet = CGaitAnaly::ReadGaitFromTable(_ttoi(m_strMRNCode), nDiagSN, strDate, dwGaitPoints, &nStartPos, &nTriggerOpen, &nTriggerClose, &strDevID, &strDevAddress);
	if(!bRet)
		return FALSE;

	WA_BASIC_PARA wbp = {0};
	wbp.dwSize = sizeof(WA_BASIC_PARA);
	wbp.dwOpenThr = nTriggerOpen;
	wbp.dwCloseThr = nTriggerClose;
	
	RECT rectUpHalf		= {0};
	rectUpHalf.left		= 0;
	rectUpHalf.top		= 0;
	rectUpHalf.right	= pInfo->m_rectDraw.Width();
	rectUpHalf.bottom	= pInfo->m_rectDraw.Height() / 2 - PAGE_MARGIN * 4;
	
	CGaitAnaly ga;
	ga.InitGait(pDC, rectUpHalf, dwGaitPoints, nStartPos);
	ga.SetGaitPara(&wbp);
	ga.SetLineWidthMul(3);
	ga.SetDevID(strDevID);
	ga.BeginDrawPrintGaitGraph(0, MARGIN_FOR_PAGE_TITLE);
	ga.EndDrawPrintGaitGraph();
	
	PrintPageFoot(pDC, pInfo->m_rectDraw, nTotalPage, page);
	
	BOOL bPrintingOK = (pDC->EndPage() > 0);       // end page
	page++;

	return bPrintingOK;
}

BOOL CPrintReport::PrintGaitInFirstPage(CDC* pDC, CPrintInfo* pInfo)
{
	NULL_RETURN_FALSE(pDC);
	NULL_RETURN_FALSE(pInfo);
	
	CString strDateSN;
	CComboBox* pComboSnapDate = (CComboBox*)GetDlgItem(IDC_COMBO_DATES_GAIT);
	ASSERT(pComboSnapDate);
	int nSel = pComboSnapDate->GetCurSel();
	pComboSnapDate->GetLBText(nSel, strDateSN);
	
	CString strDate = strDateSN.Left(10);
	int nDiagSN = pComboSnapDate->GetItemData(nSel);
	
	int nStartPos = 0;
	int nTriggerOpen = 0;
	int nTriggerClose = 0;
	
	DWORD dwGaitPoints[GAIT_POINT_ARRAY_SIZE] = {0};
	CString strDevID;
	CString strDevAddress;
	BOOL bRet = CGaitAnaly::ReadGaitFromTable(_ttoi(m_strMRNCode), nDiagSN, strDate, dwGaitPoints, &nStartPos, &nTriggerOpen, &nTriggerClose, &strDevID, &strDevAddress);
	if(!bRet)
		return FALSE;

	//  Get Color
	DWORD dwCommVer = 0;
	COLORREF crWAColor = RGB(255, 255, 255);
	CString strSQL;
	strSQL.Format(_T("SELECT ColorIndex FROM WAColor WHERE WAAddress='%s'"), strDevAddress);
	CGYDataSet setColor(strSQL);
	if(!setColor.IsEOF())
	{
		CString strColorIndex;
		setColor.GetFieldValue(_T("ColorIndex"), strColorIndex);
		
		DWORD dwColorIndex = _ttoi(strColorIndex);
		dwColorIndex = min(dwColorIndex, 4);
		dwColorIndex = max(dwColorIndex, 0);
		crWAColor = CColorComboBox::GetWAColor(dwColorIndex);
		
		dwCommVer = 0x12;
	}
	setColor.Close();
	
	WA_BASIC_PARA wbp = {0};
	wbp.dwSize = sizeof(WA_BASIC_PARA);
	wbp.dwOpenThr = nTriggerOpen;
	wbp.dwCloseThr = nTriggerClose;
	
	RECT rectUpHalf		= {0};
	rectUpHalf.left		= 0;
	rectUpHalf.top		= 0;
	rectUpHalf.right	= pInfo->m_rectDraw.Width();
	rectUpHalf.bottom	= pInfo->m_rectDraw.Height() / 2 - PAGE_MARGIN * 4;
	
	CGaitAnaly ga;
	ga.InitGait(pDC, rectUpHalf, dwGaitPoints, nStartPos);
	ga.SetGaitPara(&wbp);
	ga.SetLineWidthMul(3);
	ga.SetDevID(strDevID);
	ga.SetCommVer(dwCommVer);
	ga.SetWAColor(crWAColor);
	ga.BeginDrawPrintGaitGraph(0, GAIT_GRAPH_Y);
	ga.EndDrawPrintGaitGraph();

	CString strMRNCode;
	m_edtSerialNo.GetWindowText(strMRNCode);
	pComboSnapDate->GetLBText(nSel, strDateSN);
	
	//  Draw date and diagnose serial no
	rectUpHalf.top = GAIT_GRAPH_Y;
	rectUpHalf.bottom = rectUpHalf.top + pInfo->m_rectDraw.Height();
	rectUpHalf.right -= PAGE_MARGIN;

	pDC->SelectObject(m_pFontBody);
	pDC->DrawText(strDateSN, &rectUpHalf, DT_SINGLELINE|DT_RIGHT|DT_TOP);

	return TRUE;
}

BOOL CPrintReport::PrintOneString(CDC* pDC, CPrintInfo* pInfo, int nTotalPage, UINT& nPageIndex, CString strTitle, CString strString, BOOL bDrawDiagSN)
{
	NULL_RETURN_FALSE(pDC);
	NULL_RETURN_FALSE(pInfo);
	
	pDC->StartPage();
	
	// title
	PrintPageTitle(pDC, pInfo, nTotalPage, nPageIndex, strTitle, bDrawDiagSN);

	//  frame rectangle
	CRect rectText;
	rectText.left		= PAGE_MARGIN;
	rectText.top		= LINE_1_Y;
	rectText.right		= pInfo->m_rectDraw.Width() - PAGE_MARGIN;
	rectText.bottom		= pInfo->m_rectDraw.Height() - PAGE_MARGIN * 3;
	pDC->Rectangle(rectText);
	
	//  text
	pDC->SelectObject(m_pFontBody);
	rectText.DeflateRect(PAGE_MARGIN, PAGE_MARGIN);
	pDC->DrawText(strString, &rectText, DT_WORDBREAK);
	
	// foot
	PrintPageFoot(pDC, pInfo->m_rectDraw, nTotalPage, nPageIndex);
	
	pDC->EndPage();
	nPageIndex++;
	
	return TRUE;
}

void CPrintReport::OnSelchangeComboDatesGait() 
{
	CComboBox* pComboSnapDate = (CComboBox*)GetDlgItem(IDC_COMBO_DATES_GAIT);
	ASSERT(pComboSnapDate);

	if(pComboSnapDate->GetCount() <= 0)
		return;

	int nSel = pComboSnapDate->GetCurSel();

	CString strSQL;
	strSQL.Format(_T("SELECT SnapID FROM GaitSnap WHERE MRNCode='%s' AND DiagSN=%d"), m_strMRNCode, nSel);
	CGYDataSet setGait(strSQL);

	CButton* pCheckGait = (CButton*)GetDlgItem(IDC_CHECK_GAIT_GRAPH);
	ASSERT(pCheckGait);

	pCheckGait->SetCheck(0);
	pCheckGait->EnableWindow(!setGait.IsEOF());
}

CString CPrintReport::GetHospitalName()
{
	CString strSQL;
	strSQL.Format(_T("SELECT ComputerNo FROM SysConfig WHERE ConfigName='SoftwareSerialNo' AND ConfigValue='%s'"), GetApp()->GetSoftwareSN());
	CGYDataSet setSysConfig(strSQL);
	
	CString strComputerNo;
	setSysConfig.GetFieldValue(_T("ComputerNo"), strComputerNo);
	
	CString strHospitalName;
	strSQL.Format(_T("SELECT ConfigValue FROM SysConfig WHERE ComputerNo=%s AND ConfigName='HospitalName'"), strComputerNo);
	setSysConfig.OpenTable(strSQL);

	if(setSysConfig.IsEOF())
	{
		strHospitalName = GetResString(IDS_SYS_A_HOSPITAL);
	}
	else
	{
		setSysConfig.GetFieldValue(_T("ConfigValue"), strHospitalName);
	}

	return strHospitalName;
}

BOOL CPrintReport::PrintZNP(CDC* pDC, CPrintInfo* pInfo, int nTotalPage, UINT& nPageIndex, BOOL bZhusu, BOOL bNow, BOOL bPast)
{
	NULL_RETURN_FALSE(pDC);
	NULL_RETURN_FALSE(pInfo);

	pDC->StartPage();

	pDC->SelectObject(m_pFontTitle);
	CString strTitle = GetResString(IDS_TABTITLE_ZHUSU);
	CSize sizeTitleSize = pDC->GetTextExtent(strTitle);

	RECT rectTitle		= {0};
	rectTitle.left		= PAGE_MARGIN;
	rectTitle.right		= pInfo->m_rectDraw.Width() - PAGE_MARGIN;
	rectTitle.top		= PAGE_MARGIN;
	rectTitle.bottom	= rectTitle.top + sizeTitleSize.cy;

	int nFrameHeight = (pInfo->m_rectDraw.Height() - PAGE_MARGIN * 3) / 3 - sizeTitleSize.cy - sizeTitleSize.cy * MARGIN_TITLE_FRAME - sizeTitleSize.cy * MARGIN_FRAME_TITLE;

	CRect rectFrame;
	rectFrame.left		= PAGE_MARGIN;
	rectFrame.right		= pInfo->m_rectDraw.Width() - PAGE_MARGIN;
	rectFrame.top		= rectTitle.bottom + sizeTitleSize.cy * MARGIN_TITLE_FRAME;
	rectFrame.bottom	= rectFrame.top + nFrameHeight;

	if(bZhusu)
	{
		pDC->DrawText(strTitle, &rectTitle, DT_SINGLELINE|DT_CENTER);
		pDC->Rectangle(rectFrame);

		CString strSQL;
		strSQL.Format(_T("SELECT InfoText FROM PatMedInfoText WHERE MedicalRecordNo='%s' AND InfoType=%d"), m_strMRN, CZhusuPage::MedicalInfoType);
		
		CString strText;
		CGYDataSet tblInfoText(strSQL);
		if(!tblInfoText.IsEOF())
		{
			tblInfoText.GetFieldValue(_T("InfoText"), strText);
		}

		CRect rectText = rectFrame;
		rectText.DeflateRect(PAGE_MARGIN, PAGE_MARGIN);

		pDC->SelectObject(m_pFontBody);
		pDC->DrawText(strText, &rectText, DT_WORDBREAK);

		rectTitle.top		= rectFrame.bottom + sizeTitleSize.cy * MARGIN_FRAME_TITLE;
		rectTitle.bottom	= rectTitle.top + sizeTitleSize.cy;

		rectFrame.top		= rectTitle.bottom + sizeTitleSize.cy * MARGIN_TITLE_FRAME;
		rectFrame.bottom	= rectFrame.top + nFrameHeight;
	}

	if(bNow)
	{
		strTitle = GetResString(IDS_TABTITLE_NOWHIST);

		pDC->SelectObject(m_pFontTitle);
		pDC->DrawText(strTitle, &rectTitle, DT_SINGLELINE|DT_CENTER);
		pDC->Rectangle(rectFrame);
		
		CString strSQL;
		strSQL.Format(_T("SELECT InfoText FROM PatMedInfoText WHERE MedicalRecordNo='%s' AND InfoType=%d"), m_strMRN, CHisNowPage::MedicalInfoType);
		
		CString strText;
		CGYDataSet tblInfoText(strSQL);
		if(!tblInfoText.IsEOF())
		{
			tblInfoText.GetFieldValue(_T("InfoText"), strText);
		}
		
		CRect rectText = rectFrame;
		rectText.DeflateRect(PAGE_MARGIN, PAGE_MARGIN);
		
		pDC->SelectObject(m_pFontBody);
		pDC->DrawText(strText, &rectText, DT_WORDBREAK);
		
		rectTitle.top		= rectFrame.bottom + sizeTitleSize.cy * MARGIN_FRAME_TITLE;
		rectTitle.bottom	= rectTitle.top + sizeTitleSize.cy;
		
		rectFrame.top		= rectTitle.bottom + sizeTitleSize.cy * MARGIN_TITLE_FRAME;
		rectFrame.bottom	= rectFrame.top + nFrameHeight;
	}
	
	if(bPast)
	{
		strTitle = GetResString(IDS_TABTITLE_PASTHIST);
		
		pDC->SelectObject(m_pFontTitle);
		pDC->DrawText(strTitle, &rectTitle, DT_SINGLELINE|DT_CENTER);
		pDC->Rectangle(rectFrame);
		
		CString strSQL;
		strSQL.Format(_T("SELECT InfoText FROM PatMedInfoText WHERE MedicalRecordNo='%s' AND InfoType=%d"), m_strMRN, CHisPastPage::MedicalInfoType);
		
		CString strText;
		CGYDataSet tblInfoText(strSQL);
		if(!tblInfoText.IsEOF())
		{
			tblInfoText.GetFieldValue(_T("InfoText"), strText);
		}
		
		CRect rectText = rectFrame;
		rectText.DeflateRect(PAGE_MARGIN, PAGE_MARGIN);
		
		pDC->SelectObject(m_pFontBody);
		pDC->DrawText(strText, &rectText, DT_WORDBREAK);
	}

	// foot
	PrintPageFoot(pDC, pInfo->m_rectDraw, nTotalPage, nPageIndex);
	
	pDC->EndPage();
	nPageIndex++;

	return TRUE;
}
